﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Net;

namespace SSVisionCom
{
    public class TcpNet
    {
        /// <summary>
        /// 这是一个处理消息的方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="msg"></param>
        private delegate void ProcessMsg(string ip, string msg);
        /// <summary>
        /// 这也是一个处理消息的方法
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="msg"></param>
        public delegate void setProcessMsg(string ip, string msg);
        /// <summary>
        /// 监听服务的IP
        /// </summary>
        private string IpAddress = "0.0.0.0";
        /// <summary>
        /// 监听服务的端口
        /// </summary>
        private int port;
        /// <summary>
        /// 用于存放Socket的列表
        /// </summary>
        public Dictionary<string, Socket> SocketList = new Dictionary<string, Socket>();
        /// <summary>
        /// 用于监听的Socket
        /// </summary>
        private Socket Listener;
        /// <summary>
        /// 消息缓冲区
        /// </summary>
        public byte[] buffer = new byte[1024];
        /// <summary>
        /// 客户端的数量
        /// </summary>
        public int ClientCount { get; set; }
        /// <summary>
        /// 实例一个处理消息的办法
        /// </summary>
        private ProcessMsg MsgProcess;
        /// <summary>
        /// 存放当前运行状态的相关信息
        /// </summary>
        public List<string> RunMsg = new List<string>();
        /// <summary>
        /// 开启一个监听服务
        /// </summary>
        /// <param name="port"></param>
        /// <returns></returns>
        public RunResult Start(int port)
        {
            this.port = port;
            RunResult runresult = new RunResult();
            try
            {
                Listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint IPEndPoint = new IPEndPoint(IPAddress.Parse(IpAddress), port);
                Listener.Bind(IPEndPoint);
                Listener.Listen(ClientCount);
                Listener.BeginAccept(Accept, null);

                runresult.resultID = 0;
                runresult.msg = "创建服务成功";
            }
            catch (Exception error)
            {
                runresult.resultID = -1;
                runresult.msg = "创建服务失败 /r/n" + error.Message;
            }
            return runresult;
        }
        public bool GetConnect(string ip)
        {
            bool Result = false;
            foreach (KeyValuePair<string, Socket> i in SocketList)
            {
                if (i.Key == ip)
                {
                    Result = true;
                }
            }
            return Result;
        }
        /// <summary>
        /// 停止一个服务
        /// </summary>
        public void Stop()
        {
            try
            {
                Listener.Shutdown(SocketShutdown.Both);
                Listener.Close();
                Listener.Dispose();
            }
            catch
            {
            }
        }
        /// <summary>
        /// 当有客户端连接时的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void Accept(IAsyncResult ar)
        {
            try
            {
                Socket socket = Listener.EndAccept(ar);
                string adr = socket.RemoteEndPoint.ToString();
                string[] name = adr.Split(':');
                Console.WriteLine(name[0] + "已连接");
                bool checkResult = false;
                foreach (KeyValuePair<string, Socket> i in SocketList)
                {
                    if (i.Key == name[0])
                    {
                        checkResult = true;
                    }
                }
                if (checkResult == true)
                {
                    SocketList.Remove(name[0]);
                }
                SocketList.Add(name[0], socket);
                socket.BeginReceive(buffer, 0, 1024, SocketFlags.None, ReceiveCb, socket);
                Listener.BeginAccept(Accept, null);
            }
            catch
            {

            }
        }
        /// <summary>
        /// 当有消息接收到的回调函数
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveCb(IAsyncResult ar)
        {
            Socket read = (Socket)ar.AsyncState;
            string ClientName = "";
            try
            {
                int count = read.EndReceive(ar);
                string[] name = read.RemoteEndPoint.ToString().Split(':');
                if (count <= 0)
                {
                    Addinfo(name[0] + ": 客户端已经主动断开");
                    read.Close();
                    SocketList.Remove(name[0]);
                }
                string info = Encoding.Default.GetString(buffer, 0, count);
                ClientName = name[0];
                MsgProcess(name[0], info);
                read.BeginReceive(buffer, 0, 1024, SocketFlags.None, ReceiveCb, read);
            }

            catch (Exception error)
            {

                Console.WriteLine(error.Message);
                return;
            }
        }
        /// <summary>
        /// 这是处理消息的回调实现
        /// </summary>
        /// <param name="msgHandle"></param>
        public void SetMsgHandle(setProcessMsg msgHandle)
        {
            MsgProcess = new ProcessMsg(msgHandle);
        }




        private void Addinfo(string info)
        {

            if (RunMsg.Count > 20)
            {
                RunMsg.RemoveAt(0);
            }
            RunMsg.Add(info);
        }


        /// <summary>
        /// 这是主动连接一个服务端的方法
        /// </summary>
        /// <param name="ip">服务端的地址</param>
        /// <param name="port">服务端口</param>
        public bool Connect(string ip, int port)
        {
            
            try
            {
                Socket clnet = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPAddress ipaddr = IPAddress.Parse(ip);
                IPEndPoint ipendpoint = new IPEndPoint(ipaddr, port);
                clnet.Connect(ipendpoint);
                SocketList.Add(ip, clnet);
                clnet.BeginReceive(buffer, 0, 1024, SocketFlags.None, ReceiveCb, clnet);
                return true;
            }
            catch (Exception error)
            {
                Console.WriteLine(error.Message);
                return false;
            }

        }
        public void Close()
        {
            if(SocketList.Count >0)
            {
                foreach (KeyValuePair<string, Socket> i in SocketList)
                {
                    i.Value.Close();

                }
            }
        }
        /// <summary>
        /// 这是主动向客户端发送消息的办法
        /// </summary>
        /// <param name="ClientIP">客户端地址</param>
        /// <param name="info">客户端口</param>
        public void SendMsg(string ClientIP, string info)
        {
            byte[] msg = new byte[1024 * 1024];
            msg = Encoding.Default.GetBytes(info);
            SocketList[ClientIP].Send(msg);
        }
        /// <summary>
        /// 获取当前客户端的连接数量
        /// </summary>
        /// <returns></returns>
        public int GetConnectCount()
        {
            return SocketList.Count;
        }

    }
    public class RunResult
    {
        /// <summary>
        /// 以数字形式返回操作结果
        /// </summary>
        public int resultID;
        /// <summary>
        /// 以Boolean形式返回操作结果
        /// </summary>
        public bool resultStatic;
        /// <summary>
        /// 以字符串形式返回结果
        /// </summary>
        public string msg;
    }
}
